<?php

namespace app\admin\controller;

use app\admin\model\Bot;
use App\admin\validate\Bot as ValidateBot;
use App\telegram\FileType;
use Illuminate\Support\Arr;
use plugin\admin\app\controller\Base;
use support\Request;

use Respect\Validation\Exceptions\ValidationException;
use support\Db;
use Telegram\Bot\Api;
use Throwable;
use Webman\RedisQueue\Redis;

class BotController extends Base
{
    public function index(Request $request)
    {
        if ($request->isAjax()) {

            $data = (new Bot)->withCount(['backups'])->when($request->get('bot_id'), function ($query, $bot_id) {
                $query->where('bot_id', $bot_id);
            }, function ($query) {
                $query->where('bot_id', 0);
            })->paginate($request->get('limit', 10));
            return json(['code' => 0, 'count' => $data->total(), 'data' => $data->items()]);
        }
        return view('bot/index');
    }

    public function create(Request $request)
    {
        if ($request->method() == 'POST') {
            try {
                $data = (new ValidateBot)->check($request->post());
            } catch (ValidationException $e) {
                return $this->json(401, $e->getMessage());
            } catch (\Exception $e) {
                return $this->json(1, $e->getMessage());
            }
            // 
            Db::beginTransaction();
            try {
                // master save
                $master_bot = new Bot;
                $master_bot->name = $data['name'];
                $master_bot->token = $data['token'];
                $master_bot->enable = (bool)$data['enable'];
                $master_bot->save();
                // belongs save
                if ($data['backup_user_id']) {
                    foreach ($data['backup_user_id'] as $key => $backup_user_id) {
                        throw_if($data['backup_token'][$key] == $master_bot->token, \Exception::class, "备份机器人token不能与主机器人token相同");
                        $backup_bot = new Bot;
                        $backup_bot->name = $master_bot->name . '的备份机器人(' . ($key + 1) . ')';
                        $backup_bot->token = $data['backup_token'][$key];
                        $backup_bot->backup_user_id = $backup_user_id;
                        $backup_bot->enable = (bool)config('app.debug');
                        $backup_bot->bot_id = $master_bot->id;
                        $backup_bot->save();
                    }
                }
                Db::commit();
                Redis::send('set_bot_hook', ['id'=>$master_bot->id]);
                return $this->json(0);
            } catch (\Throwable $e) {
                Db::rollBack();
                return $this->json(1, $e->getMessage());
            }
        }

        return view('bot/create');
    }

    public function edit(Request $request)
    {
        $id = $request->get('id');
        $master_bot = (new Bot)->where('id', $id)->where('bot_id', 0)->first();
        if ($request->method() == 'POST') {            
            if (!$master_bot) return $this->json(1, '机器人不存在');
            try {
                $data = (new ValidateBot)->check($request->post());
            } catch (ValidationException $e) {
                return $this->json(401, $e->getMessage());
            } catch (\Exception $e) {
                return $this->json(1, $e->getMessage());
            }
            Db::beginTransaction();
            try {
                // master save
                $master_bot->name = $data['name'];
                $master_bot->token = $data['token'];
                $master_bot->enable = (bool)$data['enable'];
                $master_bot->save();
                // delete backups
                $master_bot->backups()->delete();
                // belongs save
                if ($data['backup_user_id']) {
                    foreach ($data['backup_user_id'] as $key => $backup_user_id) {
                        throw_if($data['backup_token'][$key] == $master_bot->token, \Exception::class, "备份机器人token不能与主机器人token相同");
                        $backup_bot = new Bot;
                        $backup_bot->name = $master_bot->name . '的备份机器人(' . ($key + 1) . ')';
                        $backup_bot->token = $data['backup_token'][$key];
                        $backup_bot->backup_user_id = $backup_user_id;
                        $backup_bot->enable = (bool)config('app.debug');
                        $backup_bot->bot_id = $master_bot->id;
                        $backup_bot->save();
                    }
                }
                Db::commit();
                Redis::send('set_bot_hook', ['id'=>$master_bot->id]);
                return $this->json(0);
            } catch (\Throwable $e) {
                Db::rollBack();
                return $this->json(1, $e->getMessage());
            }
            return ;
        }

        if(!$master_bot){
            return view('404', ['msg'=>'机器人不存在']);
        }
        return view('bot/edit', ['master_bot'=>$master_bot]);
    }

    public function delete(Request $request){
        $id = $request->get('id');
        $bot = (new Bot)->where('id', $id)->first();
        if(!$bot) return $this->json(1, '机器人不存在');
        Db::beginTransaction();
        try{
            $bot->backups()->delete();
            $bot->delete();
            Db::commit();
            return $this->json(0);
        }catch(Throwable $e){
            Db::rollBack();
            return $this->json(1, '删除失败');
        }
    }

    public function status(Request $request){
        $id = $request->get('id');
        $bot = (new Bot)->where('id', $id)->first();
        if(!$bot) return $this->json(1, '机器人不存在');
        try{
            $telegram = new Api($bot->token);
            $webhook = $telegram->getWebhookInfo();
            return json(['code'=>0, 'data'=>$webhook->get('url') == getTelegramHookUrl($bot->token)]);
        }catch(\Exception $e){
            return json(['code'=>1, 'msg'=>$e->getMessage()]);
        }
        
    }

    public function settings(Request $request){
        $id = $request->get('id');
        $bot = (new Bot)->where('id', $id)->where('bot_id', 0)->first();
        if($request->method() == 'POST'){
            
            foreach(FileType::cases() as $type){
                $bot->filePerfixs()->updateOrCreate(['type'=>$type->value],['perfix'=>Arr::get($request->post('type'),$type->value,'')]);
            }

            return $this->json(0);
        }


        if(!$bot) return view('404', ['msg'=>'机器人不存在']);
        $perfixs = $bot->filePerfixs()->pluck('perfix', 'type');
        $file_types = [];
        foreach(FileType::cases() as $type){
            $file_types[] = ['type'=>$type->value, 'title'=>$type->text(), 'perfix'=>$type->perfix($perfixs->toArray())];
        }


        return view('bot/settings', ['file_types'=>$file_types]);
    }
}
